home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / sound / vdigit.zip / VPMOD.ASM < prev    next >
Assembly Source File  |  1989-06-24  |  19KB  |  840 lines

  1. page 58,132
  2. .286c
  3. .MODEL LARGE
  4.  
  5. ;**********************************************************************
  6. ;*                                                                    *
  7. ;*                             Equates                                *
  8. ;*                                                                    *
  9. ;**********************************************************************
  10.  
  11. tccount        equ    72    ;reload count to produce 16572 Hz
  12. countmax_18hz    equ    910    ;ratio of new timer rate to old rate
  13.  
  14. tcaddrc        equ    43h    ;timer/counter control register address
  15. tcaddrd        equ    40h    ;timer/counter data register zero
  16.  
  17. tcmode        equ    34h    ;mode control byte for timer/counter
  18.  
  19. ppiaddr        equ    61h    ;programmable peripheral interface address
  20.  
  21. ;**********************************************************************
  22. ;*                                                                    *
  23. ;*                             Macros                                 *
  24. ;*                                                                    *
  25. ;**********************************************************************
  26.  
  27. ljz    macro    dest
  28.     local    skip
  29.     jnz    skip
  30.     jmp    dest
  31. skip:
  32.     endm
  33.  
  34. ljb    macro    dest
  35.     local    skip
  36.     jnb    skip
  37.     jmp    dest
  38. skip:
  39.     endm
  40.  
  41. ljbe    macro    dest
  42.     local    skip
  43.     jnbe    skip
  44.     jmp    dest
  45. skip:
  46.     endm
  47.  
  48. ;**********************************************************************
  49. ;*                                                                    *
  50. ;*                         Global variables                           *
  51. ;*                                                                    *
  52. ;**********************************************************************
  53.  
  54. .DATA
  55.         even        ;don't put these on an odd boundary
  56.  
  57. blockaddr    dd    0    ;beginning of memory block
  58. blocksize    dd    0    ;size of memory block
  59. blockend    dd    0    ;last address of memory block + 1
  60. currentaddr    dd    0    ;pointer to current play position in memory
  61. endaddr        dd    0    ;address of last byte to be played + 1
  62. datalength    dd    0    ;total number of data bytes
  63. datacount    dd    0    ;number of data bytes already played
  64. filladdr    dd    0    ;address of next byte to be filled from disk
  65. fillcount    dd    0    ;number of bytes already read from disk
  66.  
  67. goflag        dw    0    ;indicates whether playback is in progress
  68. fdoneflag    dw    0    ;indicates whether unread data remains in file
  69. fileflag    dw    0    ;indicates whether data is read from a file
  70. filehandle    dw    0    ;handle of file containing voice data
  71. hookedflag    dw    0    ;indicates whether the interrupt is hooked
  72. countfor_18hz    dw    0    ;counter to determine when to call BIOS
  73.  
  74. shiftcount    db    0    ;current bit position within byte
  75.  
  76. ;**********************************************************************
  77. ;*                                                                    *
  78. ;*                               Code                                 *
  79. ;*                                                                    *
  80. ;**********************************************************************
  81.  
  82. .CODE
  83.  
  84. bios_timer_routine    dd    0    ;we keep this in the code segment
  85.                     ; for access through the CS register
  86.                     ; since the other segment registers
  87.                     ; will contain unknown values when
  88.                     ; this is needed
  89.  
  90.     assume    ds:DGROUP
  91.  
  92. ;**********************************************************************
  93. ;*             Speed up the timer tick and set "goflag"               *
  94. ;**********************************************************************
  95.  
  96. startvoice    proc    near
  97.  
  98.     pushf
  99.     cli
  100.     mov    al,tcmode
  101.     out    tcaddrc,al
  102.     mov    ax,tccount
  103.     out    tcaddrd,al
  104.     mov    al,ah
  105.     out    tcaddrd,al
  106.     mov    shiftcount,0
  107.     mov    countfor_18hz,countmax_18hz
  108.     mov    goflag,1
  109.     popf
  110.     ret
  111.  
  112. startvoice    endp
  113.  
  114. ;**********************************************************************
  115. ;*         Slow the timer tick to normal and clear "goflag"           *
  116. ;**********************************************************************
  117.  
  118. stopvoice    proc    near
  119.  
  120.     pushf
  121.     cli
  122.     mov    al,tcmode
  123.     out    tcaddrc,al
  124.     mov    al,0
  125.     out    tcaddrd,al
  126.     out    tcaddrd,al
  127.     mov    goflag,0
  128.     mov    fdoneflag,0
  129.     popf
  130.     ret
  131.  
  132. stopvoice    endp
  133.  
  134. ;**********************************************************************
  135. ;*                   Interrupt service routine                        *
  136. ;**********************************************************************
  137.  
  138. timer_tick    proc    far
  139.  
  140.     push    ds
  141.     push    bx
  142.     push    es
  143.     push    ax
  144.     push    cx
  145.  
  146.     mov    ax,DGROUP
  147.     mov    ds,ax
  148.  
  149.     cmp    goflag,0
  150.     je    chain_exit
  151.  
  152.     les    bx,currentaddr
  153.     mov    ah,es:[bx]
  154.     mov    cl,shiftcount
  155.     rol    ah,cl
  156.     rol    ah,2
  157.     and    ah,02h
  158.     in    al,ppiaddr
  159.     and    al,0FCh
  160.     or    al,ah
  161.     out    ppiaddr,al
  162.     inc    cl
  163.     and    cl,07h
  164.     mov    shiftcount,cl
  165.     jnz    exit_decide
  166.  
  167.     mov    ax,es
  168.     inc    bx
  169.     jnz    check_wrap
  170.     add    ax,1000h
  171. check_wrap:
  172.     cmp    bx,word ptr blockend
  173.     jne    check_end
  174.     cmp    ax,word ptr blockend+2
  175.     jne    check_end
  176.     mov    bx,word ptr blockaddr
  177.     mov    ax,word ptr blockaddr+2
  178. check_end:
  179.     cmp    bx,word ptr endaddr
  180.     jne    save_cur_addr
  181.     cmp    ax,word ptr endaddr+2
  182.     jne    save_cur_addr
  183.     call    stopvoice
  184.     jmp    short exit_decide
  185. save_cur_addr:
  186.     mov    word ptr currentaddr,bx
  187.     mov    word ptr currentaddr+2,ax
  188.     add    word ptr datacount,1
  189.     adc    word ptr datacount+2,0
  190.  
  191. exit_decide:
  192.     dec    countfor_18hz
  193.     jnz    nochain_exit
  194.     mov    countfor_18hz,countmax_18hz
  195.  
  196. chain_exit:
  197.     pop    cx
  198.     pop    ax
  199.     pop    es
  200.     pop    bx
  201.     pop    ds
  202.     jmp    cs:bios_timer_routine
  203.  
  204. nochain_exit:
  205.     mov    al,20h
  206.     out    20h,al
  207.     pop    cx
  208.     pop    ax
  209.     pop    es
  210.     pop    bx
  211.     pop    ds
  212.     iret
  213.  
  214. timer_tick    endp
  215.  
  216. ;**********************************************************************
  217. ;*                   Initialization procedure                         *
  218. ;**********************************************************************
  219.  
  220. ;This routine should be called exactly one time before any of the other
  221. ; routines in this package are called. It takes no parameters, but returns
  222. ; a value indicating success or failure as follows:
  223.  
  224. ;Return value        Meaning
  225. ;------------        -------
  226. ;     0              success
  227. ;     1              voice package already initialized
  228. ;     2              wrong CPU, won't run on 8088 or 8086
  229.  
  230.     public    PVOICE_INIT
  231.  
  232. PVOICE_INIT    proc    far
  233.  
  234.     push    sp
  235.     pop    ax
  236.     cmp    ax,sp
  237.     je    vi_test
  238.     mov    ax,2
  239.     ret
  240.  
  241. vi_test:
  242.     cmp    hookedflag,0
  243.     je    vi_hook
  244.     mov    ax,1
  245.     ret
  246.  
  247. vi_hook:
  248.     enter    0,0
  249.     push    si
  250.     push    di
  251.  
  252.     push    ds
  253.     lea    dx,PVOICE_CBREAK
  254.     mov    ax,seg PVOICE_CBREAK
  255.     mov    ds,ax
  256.     mov    ax,2523h
  257.     int    21h
  258.     pop    ds
  259.  
  260.     push    ds
  261.     mov    ax,3508h
  262.     int    21h
  263.     mov    word ptr cs:bios_timer_routine,bx
  264.     mov    word ptr cs:bios_timer_routine+2,es
  265.     lea    dx,timer_tick
  266.     mov    ax,seg timer_tick
  267.     mov    ds,ax
  268.     mov    ax,2508h
  269.     int    21h
  270.     pop    ds
  271.  
  272.     pop    di
  273.     pop    si
  274.     mov    hookedflag,1
  275.     sub    ax,ax
  276.     leave
  277.     ret
  278.  
  279. PVOICE_INIT    endp
  280.  
  281. ;**********************************************************************
  282. ;*                      Cleanup procedure                             *
  283. ;**********************************************************************
  284.  
  285. ;This will restore the interrupt 8 vector to its original state. This
  286. ; routine MUST be called before the main program exits to DOS, unless:
  287. ; (a) the program has never called PVOICE_INIT, or (b) the program is
  288. ; becoming memory-resident.
  289.  
  290. ;There are no parameters. The return values are 0 for success or 1 if
  291. ; the interrupt vector was not in fact hooked.
  292.  
  293.     public    PVOICE_CLEANUP
  294.  
  295. PVOICE_CLEANUP    proc    far
  296.  
  297.     cmp    hookedflag,1
  298.     je    vc_unhook
  299.     mov    ax,1
  300.     ret
  301.  
  302. vc_unhook:
  303.     enter    0,0
  304.     push    si
  305.     push    di
  306.     call    stopvoice
  307.     push    ds
  308.     lds    dx,cs:bios_timer_routine
  309.     mov    ax,2508h
  310.     int    21h
  311.     pop    ds
  312.     pop    di
  313.     pop    si
  314.     mov    hookedflag,0
  315.     sub    ax,ax
  316.     leave
  317.     ret
  318.  
  319. PVOICE_CLEANUP    endp
  320.  
  321. ;**********************************************************************
  322. ;*                Vector restore for Control-Break                    *
  323. ;**********************************************************************
  324.  
  325.     public    PVOICE_CBREAK
  326.  
  327. PVOICE_CBREAK    proc    far
  328.  
  329.     pusha
  330.     push    ds
  331.     push    es
  332.  
  333.     mov    ax,DGROUP
  334.     mov    ds,ax
  335.     call    stopvoice
  336.     call    PVOICE_CLEANUP
  337.  
  338.     pop    es
  339.     pop    ds
  340.     popa
  341.     stc
  342.     ret
  343.  
  344. PVOICE_CBREAK    endp
  345.  
  346. ;**********************************************************************
  347. ;*                "File read catch-up" procedure                      *
  348. ;*************